/**
 * 
 */
package kr.co.insoft.auth.security;

import java.util.HashSet;
import java.util.List;

import kr.co.insoft.auth.mapper.security.UserDetailsMapper;
import kr.co.insoft.auth.model.organization.OrganizationUserEntityModel;
import kr.co.insoft.auth.model.security.Role;
import kr.co.insoft.auth.model.security.User;
import kr.co.insoft.auth.repository.organization.OrganizationUserRepository;
import kr.co.insoft.framework.exceptions.ExceptionCode;
import kr.co.insoft.framework.exceptions.RepositoryException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.util.Assert;

/**
 * @author IN-SOFT Inc. GoodwillDD(sylee@in-soft.co.kr)
 * 
 */
public class UserDetailsService implements
		org.springframework.security.core.userdetails.UserDetailsService {

	@Autowired
	UserDetailsMapper userDetailsMapper;

	@Autowired
	OrganizationUserRepository organizationUserRepository;

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.springframework.security.core.userdetails.UserDetailsService#
	 * loadUserByUsername(java.lang.String)
	 */
	@Override
	public UserDetails loadUserByUsername(String username)
			throws UsernameNotFoundException {
		try {
			User user = this.findByUsername(username);
			user.addRoles(findRoleByUserid(user.getId()));
			List<OrganizationUserEntityModel> orgs = organizationUserRepository
					.getUserOrgs(user.getId());
			for(OrganizationUserEntityModel org : orgs) {
				user.addRole(new Role("ORG_"+org.getOrgid()));				
			}
			return user;
		} catch (UsernameNotFoundException e) {
			throw new UsernameNotFoundException(
					ExceptionCode.USER_NOT_FOUND_EXCEPTION);
		} catch (RepositoryException e) {
			throw new UsernameNotFoundException(
					ExceptionCode.REPOSITORY_EXCEPTION, e);
		}
	}

	HashSet<Role> findRoleByUserid(Long id) throws RepositoryException {
		try {
			List<Role> roles = userDetailsMapper.findRoleByUserid(id);
			return new HashSet<Role>(roles);
		} catch (Exception e) {
			throw new RepositoryException(ExceptionCode.REPOSITORY_EXCEPTION, e);
		}
	}

	User findByUsername(String username) throws RepositoryException,
			UsernameNotFoundException {
		try {
			Assert.notNull(username);
		} catch (IllegalArgumentException e) {
			throw new RepositoryException(ExceptionCode.ARGUMENT_ERROR);
		}

		try {
			User user = userDetailsMapper.findByUsername(username);
			Assert.notNull(user);
			return user;
		} catch (IllegalArgumentException e) {
			throw new UsernameNotFoundException(
					ExceptionCode.USER_NOT_FOUND_EXCEPTION);
		} catch (Exception e) {
			throw new RepositoryException(ExceptionCode.REPOSITORY_EXCEPTION, e);
		}
	}

}
